<template>
  <div class="dropdown-menu">
    <template v-if="items.length">
      <div :class="['list', { 'is-selected': index === selectedIndex }]" v-for="(item, index) in items" :key="index"
        @click="selectItem(index)">
        {{ typeof item === 'string' ? item : item.name }}
      </div>
    </template>
    <div class="item" v-else>No result</div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'

interface Props {
  items: Array<string | { id: string; name: string }>
  command: (params: { id: string }) => void
}

interface KeyDownEvent {
  event: KeyboardEvent
}

const props = defineProps<Props>()

const selectedIndex = ref(0)

// Watch for items changes and reset selectedIndex
watch(() => props.items, () => {
  selectedIndex.value = 0
})

const upHandler = () => {
  selectedIndex.value = (selectedIndex.value + props.items.length - 1) % props.items.length
}

const downHandler = () => {
  selectedIndex.value = (selectedIndex.value + 1) % props.items.length
}

const enterHandler = () => {
  selectItem(selectedIndex.value)
}

const selectItem = (index: number) => {
  const item = props.items[index]

  if (item) {
    const id = typeof item === 'string' ? item : item.id
    const name = typeof item === 'string' ? item : item.name
    props.command({ id, name })
  }
}

const onKeyDown = ({ event }: KeyDownEvent): boolean => {
  if (event.key === 'ArrowUp') {
    upHandler()
    return true
  }

  if (event.key === 'ArrowDown') {
    downHandler()
    return true
  }

  if (event.key === 'Enter') {
    enterHandler()
    return true
  }

  return false
}

// Expose methods for parent component
defineExpose({
  onKeyDown
})
</script>

<style lang="scss">
/* Dropdown menu */
.dropdown-menu {
  background: #fff;
  border: 1px solid #f1eded;
  border-radius: 2px;
  box-shadow: 0px 12px 33px 0px rgba(0, 0, 0, .06), 0px 3.618px 9.949px 0px rgba(0, 0, 0, .04);
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: auto;
  padding: 10px 15px;
  position: relative;
  max-height: 200px;

  .list {
    text-align: left;
    max-width: 200px;
    display: flex;
    align-items: center;
    min-width: 120px;
    padding: 5px 10px;
    cursor: pointer;
    border-radius: 8px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    &:hover,
    &:hover.is-selected {
      background-color: rgba(61, 37, 20, .12);
    }

    &.is-selected {
      background-color: rgba(61, 37, 20, .06);
    }
  }
}
</style>